﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SN.Data;
using Agro.Models;
using SN.Core;
using System.Data;

namespace Agro.Services
{
    public class BaseService : IBaseService
    {

        public static DbSession DB
        {
            get
            {
                return SN.Data.DbSessionFactory.GetDbSession();
            }
        }

        public T GetEntity<T>(WhereClip where) where T : Entity
        {
            return DB.Single<T>(where);
        }

        public IList<T> GetEntityList<T>(WhereClip where) where T : Entity
        {
            return DB.From<T>().Where(where).ToList();
        }

        public IList<T> GetEntityList<T>(WhereClip where, QueryBase query) where T : Entity
        {
            return DB.GetEntityList<T>(where, query);
        }

        public object GetField<T>(Field field, WhereClip where) where T : Entity
        {
            return DB.Field<T>(field, where);
        }

        public string GetOrganizationName(string organizationid)
        {
            T_Organization Organization = new T_Organization();
            Organization = DB.Single<T_Organization>(T_Organization._.Organization_ID == organizationid);

            return Organization==null ? "无" : Organization.Organization_Name;
        }

        public IList<T> GetPageList<T>(WhereClip where, QueryBase query) where T : Entity
        {
            return DB.GetEntityList<T>(where, query);
        }

        /// <summary>
        /// 获取分页数据
        /// </summary>
        /// <param name="commandText">SQL语句</param>
        /// <param name="query">QueryBase查询实体</param>
        /// <returns>DataTable</returns>
        public DataTable GetPageData(string commandText, QueryBase query)
        {

            DataTable tbResult = null;
            int startIndex, endIndex;
            endIndex = query.rows * query.page;//结束行
            startIndex = endIndex - query.rows + 1;//开始行
            StringBuilder buider = new StringBuilder();

            if (DB.ProviderType == ProviderType.IDB2 || DB.ProviderType == ProviderType.SqlServer)
            {
                /*********************利用rownum进行分页处理*****************/
                buider.AppendFormat("SELECT Z.* FROM(SELECT X.*,ROW_NUMBER() OVER (ORDER BY X.{0} {1}) AS RECORD_NO FROM (", query.sidx, query.sord);
                buider.Append(commandText);
                buider.AppendFormat(")X )Z WHERE Z.RECORD_NO >='{0}' AND Z.RECORD_NO<='{1}'", startIndex, endIndex);
                tbResult = DB.FromSql(buider.ToString()).ToTable() as DataTable;
            }
            else if (DB.ProviderType == ProviderType.Oracle)
            {

            }
            buider.Clear();
            /*************************查询记录条数********************************/
            buider.Append("SELECT COUNT(1) FROM(" + commandText + ")T");
            query.records = DB.FromSql(buider.ToString()).ToScalar<Int32>();
            query.total = (query.records - 1) / query.rows + 1;//算出总页数


            return tbResult;
        }


        /*取得上一年，上一月，上一季 的截止上报日期*/
        public IDictionary<string, DateTime> GetAllDeadline()
        {
            int nowYear, nowMonth, nowSeason;
            DateTime TempDate = DateTime.Now;
            IDictionary<string, DateTime> returnDic = new Dictionary<string, DateTime>();

            nowYear = DateTime.Now.Year;
            nowMonth = DateTime.Now.Month;
            nowSeason = (int)Math.Ceiling((decimal)DateTime.Now.Month / 3);
            IList<T_DeadlineConfig> ALLDeadline = DB.From<T_DeadlineConfig>().ToList();
            foreach (var item in ALLDeadline)
            {
                switch (item.Key)
                {
                    case "YEAR":
                        //农业厅要求年报在次年2月25日前上报，如果是闰年，应该要在配置的默认上报延迟天数上加一天
                        int delayday = item.Value;
                        if (nowYear % 4 == 0 && nowYear % 100 == 0 || nowYear % 400 == 0)
                        {
                            delayday += 1;
                        }

                        TempDate = new DateTime(nowYear - 1, 1, 1).AddDays(delayday);
                        //??运算符的作用，如果monthDeadline.FormatDay为空，则使用??后面的值进行运算，等价于monthDeadline.FormatDay==null?0:monthDeadline.FormatDay
                        if ((item.FormatDay ?? 0) > 0)//若指定了 必须格式化为固定的日
                        { TempDate = new DateTime(TempDate.Year, TempDate.Month, Convert.ToInt32(item.FormatDay)); }
                        returnDic.Add(item.Key, TempDate);
                        break;
                    case "MONTH":
                        if (nowMonth == 1)//如果是1月份，往前推一个月，就是去年的12
                            TempDate = new DateTime(nowYear - 1, 12, 1).AddDays(item.Value);
                        else
                            TempDate = new DateTime(nowYear, nowMonth - 1, 1).AddDays(item.Value);
                        //??运算符的作用，如果monthDeadline.FormatDay为空，则使用??后面的值进行运算，等价于monthDeadline.FormatDay==null?0:monthDeadline.FormatDay
                        if ((item.FormatDay ?? 0) > 0)//若指定了 必须格式化为固定的日
                        { TempDate = new DateTime(TempDate.Year, TempDate.Month, Convert.ToInt32(item.FormatDay)); }
                        returnDic.Add(item.Key, TempDate);
                        break;
                    case "SEASON":
                        //算某季度的第一个月应为，该季度*3再减2
                        if (nowSeason == 1)
                            TempDate = new DateTime(nowYear - 1, (4) * 3 - 2, 1).AddDays(item.Value);
                        else
                            TempDate = new DateTime(nowYear, (nowSeason - 1) * 3 - 2, 1).AddDays(item.Value);
                        //??运算符的作用，如果monthDeadline.FormatDay为空，则使用??后面的值进行运算，等价于monthDeadline.FormatDay==null?0:monthDeadline.FormatDay
                        if ((item.FormatDay ?? 0) > 0)//若指定了 必须格式化为固定的日
                        { TempDate = new DateTime(TempDate.Year, TempDate.Month, Convert.ToInt32(item.FormatDay)); }
                        returnDic.Add(item.Key, TempDate);
                        break;
                }
            }

            return returnDic;
        }

    }
}
